﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NetfractionHub.Network.Protocol.BASE.Factory
{
	public class FactoryINF : ProtocolMessageFactory
	{
		public enum ParameterEnum : int
		{
			SessionID = 1,
			ClientID = 2,
			PrivateID = 3,
			IPv4_Address = 4,
			IPv6_Address = 5,
			UDPv4_Port = 6,
			UDPv6_Port = 7,
			ShareSize = 8,
			SharedFilesCount = 9,
			ClientVersionIdentifier = 10,
			MaximumUploadSpeed = 11,
			MaximumDownloadSpeed = 12,
			MaximumUploadSlots = 13,
			AutomaticSlotAllocatorSpeedLimit = 14,
			MinimumUploadConnectionsForAutoSlotAlloc = 15,
			EmailAddress = 16,
			NickOrHubName = 17,
			Description = 18,
			UserNormalCount = 19,
			UserRegisteredCount = 20,
			UserOperatorCount = 21,
			Token = 22,
			ClientType = 23,
			AwayStatus = 24,
			SupportedFeatures =25,
			RefererURL = 26,
			FailoverAddresses = 27
		}

		public FactoryINF() : base()
		{
			_parameterCodes = new string[]
			{ "ID", "PD", "I4", "I6", "U4", "U6", "SS", "SF", "VE", "US", "DS", "SL", "AS", 
				"AM", "EM", "NI", "DE", "HN", "HR", "HO", "TO", "CT", "AW", "SU", "RF", "FO" };
		}

		public override ProtocolMessage Create(ProtocolMessage.MessageTypeEnum messageType, Dictionary<int, object> parameters)
		{
			ProtocolMessage proto = null;
			switch (messageType)
			{
				case ProtocolMessage.MessageTypeEnum.Broadcast:
					if (!parameters.ContainsKey((int)ParameterEnum.SessionID) || parameters[(int)ParameterEnum.SessionID] == null)
						return null; // check that calling code handles this null result

					proto = new ProtocolMessage(messageType, ProtocolFeatureBASE.FeatureActions.ActionINF, parameters[(int)ParameterEnum.SessionID] as string);
					break;
				case ProtocolMessage.MessageTypeEnum.Client:
					proto = new ProtocolMessage(messageType, ProtocolFeatureBASE.FeatureActions.ActionINF);
					break;
				case ProtocolMessage.MessageTypeEnum.Direct:
					break;
				case ProtocolMessage.MessageTypeEnum.Echo:
					break;
				case ProtocolMessage.MessageTypeEnum.Feature:
					break;
				case ProtocolMessage.MessageTypeEnum.Hub:
					break;
				case ProtocolMessage.MessageTypeEnum.Info:
					proto = new ProtocolMessage(messageType, ProtocolFeatureBASE.FeatureActions.ActionINF);
					break;
				case ProtocolMessage.MessageTypeEnum.Udp:
					break;
				default:
					break;
			}

			if (proto != null)
				foreach (ParameterEnum e in parameters.Keys)
				{
					if (e != ParameterEnum.SessionID)
						proto.Parameters.Add(new ProtocolParameter(GetParameterCodeForParameter((ParameterEnum)e), parameters[(int)e].ToString()));
				}

			return proto;
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification="Method is simple, but with many required case statements.")]
		private static string GetParameterCodeForParameter(ParameterEnum param)
		{
			switch (param)
			{
				case ParameterEnum.SessionID:
					return "SessionId";
				case ParameterEnum.ClientID:
					return "ID";
				case ParameterEnum.PrivateID:
					return "PD";
				case ParameterEnum.IPv4_Address:
					return "I4";
				case ParameterEnum.IPv6_Address:
					return "I6";
				case ParameterEnum.UDPv4_Port:
					return "U4";
				case ParameterEnum.UDPv6_Port:
					return "U6";
				case ParameterEnum.ShareSize:
					return "SS";
				case ParameterEnum.SharedFilesCount:
					return "SF";
				case ParameterEnum.ClientVersionIdentifier:
					return "VE";
				case ParameterEnum.MaximumUploadSpeed:
					return "US";
				case ParameterEnum.MaximumDownloadSpeed:
					return "DS";
				case ParameterEnum.MaximumUploadSlots:
					return "SL";
				case ParameterEnum.AutomaticSlotAllocatorSpeedLimit:
					return "AS";
				case ParameterEnum.MinimumUploadConnectionsForAutoSlotAlloc:
					return "AM";
				case ParameterEnum.EmailAddress:
					return "EM";
				case ParameterEnum.NickOrHubName:
					return "NI";
				case ParameterEnum.Description:
					return "DE";
				case ParameterEnum.UserNormalCount:
					return "HN";
				case ParameterEnum.UserRegisteredCount:
					return "HR";
				case ParameterEnum.UserOperatorCount:
					return "HO";
				case ParameterEnum.Token:
					return "TO";
				case ParameterEnum.ClientType:
					return "CT";
				case ParameterEnum.AwayStatus:
					return "AW";
				case ParameterEnum.SupportedFeatures:
					return "SU";
				case ParameterEnum.RefererURL:
					return "RF";
				case ParameterEnum.FailoverAddresses:
					return "FO";
				default:
					return "";
			}
		}
	}
}
